﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CoolCode.Reflection;

namespace CoolCode.Services
{
    public class DefaultServiceProvider : IServiceProvider
    {
        private string _namespace = "CoolCode.Services";
        private string _assembly = "CoolCode.Core.dll";

        public string Name { get; private set; }
        public string BinDirectory { get; set; }

        public DefaultServiceProvider(string binDirectory)
            : this(binDirectory, "DefaultService")
        {
        }

        public DefaultServiceProvider(string binDirectory, string serviceKey)
        {
            this.BinDirectory = binDirectory;
            this.Name = serviceKey;
            Initial(serviceKey);
        }

        protected void Initial(string serviceKey)
        {
            string service = System.Configuration.ConfigurationSettings.AppSettings[serviceKey];
            if (!string.IsNullOrEmpty(service))
            {
                string[] s = service.Split(',');
                _namespace = s[0].Trim();
                _assembly = s[1].Trim() + ".dll";
            }
            else
            {
                throw new NullReferenceException("Cannot found the service setting in appSettings: " + serviceKey);
            }
        }

        #region IServiceProvider Members
        internal protected virtual T ProvideService<T>() where T : class
        {
            /*注：用反射实现， 性能: 1 秒可执行30000次*/
            return CreateInstance<T>();
        }

        protected T CreateInstance<T>()
        {
            Type type = typeof(T);
            string interfaceName = type.Name;
            string className = interfaceName.Substring(1);//Remove "I"
            string assemblyFile = System.IO.Path.Combine(this.BinDirectory, _assembly);
            T t = AssemblyFactory.CreateInstance<T>(_namespace + "." + className, assemblyFile);
            return t;
        }
        #endregion

        #region IServiceProvider Members

        T IServiceProvider.ProvideService<T>()
        {
            return this.ProvideService<T>();
        }

        #endregion
    }
}
